'use client';

import { use, useEffect, useState, useRef } from 'react';
import * as signalR from '@microsoft/signalr';
import { DonationAlertData, DonationRemoteState } from '@/types/donation';
import { fetchApi } from '@/lib/utils/client';
import './style.scss';

type Props = {
	params: Promise<{ widgetToken: string }>;
};

type AlertQueueItem = {
	alertID: number;
	donationID: number;
	status: string;
	sponsorMemberID: number;
	sendName: string;
	amount: number;
	message: string|null;
	channelName?: string;
	createdAt: string;
};

const STATUS_LABEL: Record<string, string> = {
	playing: '재생 중',
	queued: '대기',
	failed: '실패',
	delivered: '완료',
	skipped: '건너뜀',
	ignored: '무시'
};

export default function RemotePage({ params }: Props) {
	const { widgetToken } = use(params);
	const apiBase = '/api/donation/remote';
	const hubUrl = process.env.NEXT_PUBLIC_API_URL + '/hubs/donation';

	const [connected, setConnected] = useState(false);
	const [state, setState] = useState<DonationRemoteState>({ isPaused: false, isAccepting: true, isAudioOnly: false, isVideoOnly: false });
	const [queue, setQueue] = useState<AlertQueueItem[]>([]);
	const [openMenuID, setOpenMenuID] = useState<number|null>(null);
	const connectionRef = useRef<signalR.HubConnection|null>(null);

	// 초기 데이터 로드 + SignalR 연결
	useEffect(() => {
		loadState();
		connectHub();
		return () => { connectionRef.current?.stop(); };
	}, []);

	const loadState = async () => {
		try {
			const res = await fetchApi<DonationRemoteState & { queue: AlertQueueItem[] }>(`${apiBase}/state/${widgetToken}`, { silent: true });
			if (res.data) {
				setState({ isPaused: res.data.isPaused, isAccepting: res.data.isAccepting, isAudioOnly: res.data.isAudioOnly, isVideoOnly: res.data.isVideoOnly });
				setQueue(res.data.queue || []);
			}
		} catch {}
	};

	const connectHub = () => {
		const conn = new signalR.HubConnectionBuilder().withUrl(hubUrl).withAutomaticReconnect().build();

		conn.on('ReceiveAlert', (data: DonationAlertData) => {
			setQueue(prev => [...prev, { alertID: data.alertID, donationID: data.donationID, status: 'queued', sponsorMemberID: data.sponsorMemberID, sendName: data.sendName, amount: data.amount, message: data.message, createdAt: data.createdAt }]);
		});

		conn.on('ReceiveState', (s: DonationRemoteState) => setState(s));
		conn.on('ReceiveSkip', () => {
			setQueue(prev => prev.map(q => q.status === 'playing' ? { ...q, status: 'skipped' } : q));
		});

		conn.start().then(() => {
			conn.invoke('JoinChannel', widgetToken);
			setConnected(true);
		}).catch(() => {});

		conn.onclose(() => setConnected(false));
		conn.onreconnected(() => { conn.invoke('JoinChannel', widgetToken); setConnected(true); });
		connectionRef.current = conn;
	};

	// 리모콘 액션
	const togglePause = async () => {
		const next = { ...state, isPaused: !state.isPaused };
		setState(next);
		await fetchApi(`${apiBase}/state`, { method: 'POST', body: { ...next, widgetToken }, silent: true });
	};

	const toggleAccepting = async () => {
		const next = { ...state, isAccepting: !state.isAccepting };
		setState(next);
		await fetchApi(`${apiBase}/state`, { method: 'POST', body: { ...next, widgetToken }, silent: true });
	};

	const toggleAudioOnly = async () => {
		const next = { ...state, isAudioOnly: !state.isAudioOnly, isVideoOnly: false };
		setState(next);
		await fetchApi(`${apiBase}/state`, { method: 'POST', body: { ...next, widgetToken }, silent: true });
	};

	const toggleVideoOnly = async () => {
		const next = { ...state, isVideoOnly: !state.isVideoOnly, isAudioOnly: false };
		setState(next);
		await fetchApi(`${apiBase}/state`, { method: 'POST', body: { ...next, widgetToken }, silent: true });
	};

	const skipCurrent = async () => {
		await fetchApi(`${apiBase}/skip/${widgetToken}`, { method: 'POST', silent: true });
	};

	const ignoreAlert = async (alertID: number) => {
		await fetchApi(`${apiBase}/ignore/${alertID}`, { method: 'POST', silent: true });
		setQueue(prev => prev.map(q => q.alertID === alertID ? { ...q, status: 'ignored' } : q));
		setOpenMenuID(null);
	};

	const resendAlert = async (alertID: number) => {
		await fetchApi(`${apiBase}/resend/${alertID}`, { method: 'POST', silent: true });
		setQueue(prev => prev.map(q => q.alertID === alertID ? { ...q, status: 'queued' } : q));
		setOpenMenuID(null);
	};

	const formatTime = (dateStr: string) => {
		const d = new Date(dateStr);
		return `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;
	};

	return (
		<div className="remote-container">
			<div className="remote-header">
				<h1>리모콘</h1>
				<span className={`connection-badge ${connected ? 'connected' : 'disconnected'}`}>
					{connected ? '연결됨' : '연결 끊김'}
				</span>
			</div>

			{/* 컨트롤 패널 */}
			<div className="control-panel">
				<button type="button" className={`control-btn ${state.isPaused ? 'active' : ''}`} onClick={togglePause}>
					{state.isPaused ? '▶ 재개' : '⏸ 일시정지'}
				</button>
				<button type="button" className={`control-btn ${!state.isAccepting ? 'danger' : ''}`} onClick={toggleAccepting}>
					{state.isAccepting ? '🔔 후원 받는 중' : '🔕 후원 안 받음'}
				</button>
				<button type="button" className={`control-btn ${state.isAudioOnly ? 'active' : ''}`} onClick={toggleAudioOnly}>
					🔊 음성만
				</button>
				<button type="button" className={`control-btn ${state.isVideoOnly ? 'active' : ''}`} onClick={toggleVideoOnly}>
					🖼 영상만
				</button>
				<button type="button" className="control-btn full-width" onClick={skipCurrent}>
					⏭ 건너뛰기
				</button>
			</div>

			{/* 후원 목록 */}
			<div className="alert-list-header">
				<h2>후원 목록</h2>
				<span className="alert-count">{queue.length}건</span>
			</div>

			<div className="alert-list">
				{queue.length === 0 && <div className="empty-list">후원 알림이 없습니다</div>}
				{queue.map(item => (
					<div key={item.alertID} className={`alert-item ${item.status}`}>
						{/* 방향 아이콘 */}
						<div className="alert-direction">
							<span>{item.sendName}</span>
							<span className="alert-arrow">→</span>
						</div>

						{/* 본문 */}
						<div className="alert-body">
							<div className="alert-body-top">
								<span className="alert-sender-name">{item.sendName}</span>
								<span className="alert-amount">{item.amount.toLocaleString()}원</span>
							</div>
							{item.message && <div className="alert-msg">{item.message}</div>}
							<div className="alert-time">{formatTime(item.createdAt)}</div>
						</div>

						{/* 상태 뱃지 */}
						<span className={`alert-status-badge status-${item.status}`}>
							{STATUS_LABEL[item.status] || item.status}
						</span>

						{/* 햄버거 메뉴 (재생 중이 아닐 때만) */}
						{item.status !== 'playing' && (
							<div className="relative">
								<button type="button" className="alert-menu-btn" onClick={() => setOpenMenuID(openMenuID === item.alertID ? null : item.alertID)}>
									⋮
								</button>
								{openMenuID === item.alertID && (
									<div className="alert-menu-dropdown">
										{(item.status === 'failed' || item.status === 'skipped') && (
											<div className="alert-menu-item" onClick={() => resendAlert(item.alertID)}>재전송</div>
										)}
										{item.status === 'queued' && (
											<div className="alert-menu-item danger" onClick={() => ignoreAlert(item.alertID)}>무시</div>
										)}
									</div>
								)}
							</div>
						)}
					</div>
				))}
			</div>
		</div>
	);
}